package org.esti.service.impl;

import org.apache.commons.io.FileUtils;
import org.esti.model.Book;
import org.esti.model.KnowledgeField;
import org.esti.model.User;
import org.esti.model.dao.BookDAO;
import org.esti.model.dao.UserDAO;
import org.esti.model.exceptions.AppraisalDoesNotExistException;
import org.esti.service.AppraisalTaskService;
import org.esti.service.BookService;
import org.esti.service.exception.NotValidBookContentTypeException;
import org.esti.service.exception.SavingBookException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * @author Artem Loginov (logart)
 */
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDAO dao;

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private AppraisalTaskService appraisalTaskService;

    @Value("${storage.bookPath}")
    private String bookPath;


    @Value("#{allowedBooksContentType}")
    private Map<String, String> allowedContentType;


    @Override
    public Book getBook(long id) {
        return dao.getBookById(id);
    }

    @Override
    public List<Book> getUserBooks(String login) {
        User user = userDAO.getByLogin(login);
        return dao.getUsersBooks(user);
    }

    @Override
    public List<Book> getKnowledgeFieldBooks(KnowledgeField knowledgeFieldId) {
        return dao.getKnowledgeFieldBooks(knowledgeFieldId);
    }

    @Override
    public void addBook(Book book, MultipartFile file) {

        if (!isValidContentType(file.getContentType())) {
            throw new NotValidBookContentTypeException(file.getContentType() + " is not valid content type for book");
        }

        String link = "books/" + book.getId() +
                "." +
                getBookExtensionByContentType(file.getContentType());

        try {

            File discFile = new File(
                    bookPath + link);
            FileUtils.writeByteArrayToFile(discFile, file.getBytes());
        } catch (IOException e) {
            throw new SavingBookException(e);
        }

        book.setLink("/resources/" + link);
        dao.update(book);
    }

    @Override
    public void deleteBook(Book book) {
        dao.deleteBook(book);
    }

    @Override
    public List<Book> getBooks() {
        return dao.getAllBooks();
    }

    @Override
    public List<Book> getLevelBooks(long id) {
        try {
            Set<KnowledgeField> knowledgeFields
                    = appraisalTaskService.getAppraisalKnowledgeFields(id);
            List<Book> books = new ArrayList<Book>();
            for (KnowledgeField knowledgeField : knowledgeFields) {
                books.addAll(getKnowledgeFieldBooks(knowledgeField));
            }
            return books;
        } catch (AppraisalDoesNotExistException ex) {
            return new ArrayList<Book>();
        }


    }

    private String getBookExtensionByContentType(String contentType) {
        return allowedContentType.get(contentType);
    }

    private boolean isValidContentType(String contentType) {
        return allowedContentType.containsKey(contentType);
    }
}
